package org.iabako.server.mail.template;

import org.iabako.server.tools.BundleMessages;
import org.iabako.server.tools.ServerTools;
import org.iabako.shared.entity.business.Notification;
import org.iabako.shared.entity.enumeration.NotificationType;
import org.iabako.shared.entity.user.Enterprise;
import org.iabako.shared.iservice.business.FinanceService;
import org.iabako.shared.tools.GenericTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Created by jose on 19/03/15.
 */

@Component
public class NotificationEmailTemplate extends IabakoMailTemplate {

    private final String tableNotification = "<center><div style='text-align:left; position:relative; max-width: 400px; width:50%; background-color: #f5f5f5; margin: 5px auto; display: table;'>_content_</div></center>";
    private final String tableResume = "<div style='position:relative; margin: 10px 0px; display: table; color:#99CC00'>_content_</div>";
    private final String rowDiv = "<div style='border-bottom:2px solid white; display: table-row; width: 100%;'>";
    private final String cardinalDiv = "<div style='border-bottom:4px solid white; display: table-cell; color:_color_; font-size: 20px; width: 50px; text-align: center; vertical-align:middle; padding: 5px 0px;'>";
    private final String textDiv = "<div style='border-bottom:4px solid white; display: table-cell; vertical-align:middle; font-size: 14px; padding: 5px'>";

    @Autowired
    FinanceService financeService;
    @Autowired
    BundleMessages messages;

    public NotificationEmailTemplate getInstance(Enterprise enterprise, List<Notification> notificationBefore,
                                                 List<Notification> notificationsAfter, String userName) {
        NotificationEmailTemplate template = new NotificationEmailTemplate();

        List<Notification> newNotifications = calculateNew(notificationBefore, notificationsAfter);

        if (newNotifications.isEmpty()) {
            return null;
        }

        //Welcome
        String msg = messages.getLabel(enterprise.getLanguage(), "notification_email_welcome", userName, GenericTools.formatDate(new Date()));
        template.textBody = msg.replace("<b>", "").replace("</b>", "");
        template.htmlBody = msg;

        //New notifications
        Map<Notification, String> notificationMap = getNotificationAsMap(enterprise, newNotifications);
        template.textBody += getNotificationsAsString(notificationMap);
        template.htmlBody += getNotificationsAsHtml(notificationMap, EmailBlock.newNotificationBlock);

        //Existent notifications
        List<Notification> existent = new ArrayList<Notification>();
        for (Notification notification : notificationsAfter) {
            if (!newNotifications.contains(notification)) {
                existent.add(notification);
            }
        }
        if (!existent.isEmpty()) {
            notificationMap = getNotificationAsMap(enterprise, existent);
            msg = messages.getLabel(enterprise.getLanguage(), "notification_email_existent");
            template.textBody += msg + getNotificationsAsString(notificationMap);
            template.htmlBody += msg + getNotificationsAsHtml(notificationMap, EmailBlock.existentNotificationBlock);
        }
        //Resume
        List<Double> resume = financeService.getPendingResume(enterprise);
        msg = messages.getLabel(enterprise.getLanguage(), "notification_email_resume", enterprise.getName());
        template.textBody += msg.replace("<b>", "").replace("</b>", "") + getResumeAsString(enterprise, resume);
        template.htmlBody += msg + getResumeAsHtml(enterprise, resume);

        //Greeting
        msg = messages.getLabel(enterprise.getLanguage(), "notification_email_greeting");
        template.textBody += msg;
        template.htmlBody += msg;

        template.htmlBody = "<div style='font-size: 13px'>" + template.htmlBody + "</div>";
        return template;
    }

    private List<Notification> calculateNew(List<Notification> notificationsInDB, List<Notification> notificationList) {
        List<Notification> newNotifications = new ArrayList<Notification>();
        for (Notification notification : notificationList) {
            boolean isAlwaysNew = notification.getType() == NotificationType.newPastExpenses
                    || notification.getType() == NotificationType.newPastInstallments
                    || notification.getType() == NotificationType.birthday
                    || notification.getType() == NotificationType.paymentRequest;

            boolean found = false;
            if (!isAlwaysNew) {
                for (Notification notificationInDB : notificationsInDB) {
                    found = notification.getType() == notificationInDB.getType();
                    if (found && notification.getCardinal() != notificationInDB.getCardinal()) {
                        newNotifications.add(notification);
                    }
                    if (found) {
                        break;
                    }
                }
            }
            if (isAlwaysNew || !found) {
                newNotifications.add(notification);
            }
        }
        return newNotifications;
    }

    private String getNotificationsAsString(Map<Notification, String> notificationMap) {
        String text = "\n\n";
        for (Notification notification : notificationMap.keySet()) {
            text += "- " + notification.getCardinal() + " " + notificationMap.get(notification) + "\n";
        }
        return text;
    }

    private String getResumeAsString(Enterprise enterprise, List<Double> resume) {
        String text = "\n\n";
        text += "- " + resume.get(0) + " " + messages.getLabel(enterprise.getLanguage(), "") + "\n";
        text += "- " + resume.get(1) + " " + messages.getLabel(enterprise.getLanguage(), "") + "\n";
        text += "- " + resume.get(2) + " " + messages.getLabel(enterprise.getLanguage(), "") + "\n";
        return text;
    }

    private enum EmailBlock {
        newNotificationBlock, existentNotificationBlock;
    }

    private String getNotificationsAsHtml(Map<Notification, String> notificationMap, EmailBlock emailBlock) {
        String htmlText = tableNotification;
        String color = emailBlock == EmailBlock.newNotificationBlock ? "#0088CC" : "#99CC00";
        String content = "";
        for (Notification notification : notificationMap.keySet()) {
            String line = rowDiv + cardinalDiv.replace("_color_", color) + "_cardinal_</div>" + textDiv + "_text_</div></div>";
            content += line.replace("_cardinal_", notification.getCardinal() + "").replace("_text_", notificationMap.get(notification));
        }
        return htmlText.replace("_content_", content);
    }

    private String getResumeAsHtml(Enterprise enterprise, List<Double> resume) {
        String htmlText = tableResume;
        String title = textDiv.replace("style='", "style='font-size:13px !important; padding: 2px 4px;").replace("padding: 5px", "");
        String number = textDiv.replace("style='", "style='font-size:16px; color:#555; padding: 2px 4px;").replace("padding: 5px", "");

        String content = rowDiv + title + "_text_</div>" + number + "_number_</div></div>";
        content = content.replace("_text_", messages.getLabel(enterprise.getLanguage(), "home_resume_clients_with_installments") + " :")
                .replace("_number_", +resume.get(0).intValue() + "");

        content += rowDiv + title + "_text_</div>" + number + "_number_</div></div>";
        content = content.replace("_text_", messages.getLabel(enterprise.getLanguage(), "home_resume_past_installments_total"))
                .replace("_number_", "$ " + ServerTools.formatAmount(enterprise.getLanguage(), resume.get(1)));

        content += rowDiv + title + "_text_</div>" + number + "_number_</div></div>";
        content = content.replace("_text_", messages.getLabel(enterprise.getLanguage(), "home_resume_pending_expenses_total"))
                .replace("_number_", "$ " + ServerTools.formatAmount(enterprise.getLanguage(), resume.get(2)));

        return htmlText.replace("_content_", content);
    }

    private Map<Notification, String> getNotificationAsMap(Enterprise enterprise, List<Notification> notificationList) {
        Map<Notification, String> notificationMap = new LinkedHashMap<Notification, String>();

        for (Notification notification : notificationList) {

            String notificationMessage = "";
            String extraParam;

            if (notification.getType() == NotificationType.futureInstallments) {
                extraParam = enterprise.getNotificationConfig().getFutureInstallments() + "";
                notificationMessage = messages.getLabel(enterprise.getLanguage(), notification.getType().getLabelKey(), extraParam);
            } else if (notification.getType() == NotificationType.futureExpenses) {
                extraParam = enterprise.getNotificationConfig().getFutureExpenses() + "";
                notificationMessage = messages.getLabel(enterprise.getLanguage(), notification.getType().getLabelKey(), extraParam);
            } else if (notification.getType() == NotificationType.stockLowerThanLimit) {
                extraParam = enterprise.getNotificationConfig().getStockLowerThanLimit() + "";
                notificationMessage = messages.getLabel(enterprise.getLanguage(), notification.getType().getLabelKey(), extraParam);
            } else {
                notificationMessage = messages.getLabel(enterprise.getLanguage(), notification.getType().getLabelKey());
            }
            notificationMap.put(notification, notificationMessage);
        }
        return notificationMap;
    }

    @Override
    public String getHtmlBody() {
        return htmlBody.replace("\n", "<br/>");
    }

    @Override
    public String getTextBody() {
        return textBody;
    }
}
